package h5

import (
	. "chess_platform/internal/common"
	"chess_platform/internal/login"
	"chess_platform/models/client"
	"chess_platform/models/h5"
	"fmt"
	"time"
)

//[client]公共对外的接口模块,不需要token
type ClientController struct {
	BaseController
}

//TODO:要对参数做校验,防止被攻击
func (b *ClientController) URLMapping() {
	b.Mapping("ShareRoom", b.ShareRoom)
	b.Mapping("ShareApp", b.ShareApp)
	b.Mapping("NewFeedback", b.NewFeedback)
	b.Mapping("JoinClub", b.JoinClub)
	b.Mapping("UserInfo", b.UserInfo)
}

// @Title 分享房间
// @Description 分享房间
// @Param   table_id   body   int   true      "桌子id"
// @Param   game_id   body    int   true      "游戏id"
// @Success 0 {string} 返回房间信息
// @router /share-room [post]
func (b *ClientController) ShareRoom() {
	type Params struct {
		TableId int64 `json:"table_id" valid:"Required"`
		GameId  int64 `json:"game_id" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	data, err := client.ShareRoom(p.TableId, p.GameId)
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}
	b.Res.Data = data
	b.ResponseSuccess()
}

// @Title 分享APP下载
// @Description 分享APP下载
// @Success 0 {string} 返回app下载地址信息
// @router /share-app [post]
func (b *ClientController) ShareApp() {
	data, err := client.ShareApp()
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}
	b.Res.Data = data
	b.ResponseSuccess()
}

// @Title 新建游戏玩家反馈
// @Description 新建游戏玩家反馈
// @Param   type         body   int        true        "标题"
// @Param   content      body   string     true        "内容"
// @Param   url          body   string     true        "多张图片的地址以"["url1","url2","url3"]"形式"
// @Success 0 {string}  状态码
// @router /new-feedback [post]
func (b *ClientController) NewFeedback() {
	type Params struct {
		Type    int64    `json:"type"`
		Content string   `json:"content"`
		Url     []string `json:"url"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if len(p.Url) > 3 {
		b.ResponseFail("最多只能上传三张图片")
		return
	}

	b.Valid.Required(p.Type, "type").Message("请选择反馈类型")
	b.Valid.Required(p.Content, "content").Message("内容不能为空")
	if !b.ValidParams(&p) {
		return
	}
	data := map[string]interface{}{
		"uid":         b.Uid,
		"type":        p.Type,
		"content":     p.Content,
		"status":      0,
		"create_time": time.Now().Unix(),
	}
	o := NewDBOrm(DBChessCenter)
	o.Begin()
	defer o.Rollback()
	fid, err := client.NewFeedback(data, o)
	if err != nil {
		o.Rollback()
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}
	dataUrl := map[string]interface{}{
		"fid": fid,
	}
	for _, v := range p.Url {
		dataUrl["url"] = v
		_, err := client.NewFeedbackUrl(dataUrl, o)
		if err != nil {
			o.Rollback()
			LogClient.Error(b.DatabaseError(err.Error()))

			return
		}
	}
	o.Commit()

	b.Res.Data = p.Url
	b.ResponseSuccess()
}

// @Title 一键加入亲友圈
// @Description 一键加入亲友圈
// @Param   union_id   body    int   true      "微信union_id"
// @Param   club_id    body    int   true      "亲友圈id"
// @Success 0 {string} 状态信息
// @router /join-club [post]
func (b *ClientController) JoinClub() {
	type Params struct {
		ClubId  int64  `json:"club_id" valid:"Required"`
		UnionId string `json:"union_id" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	//判断下此亲友圈是否需要审核之后才能加入
	club, err := client.ClubStructById(p.ClubId)
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}
	if club.Id == 0 || club.Status == ClubDismiss { //不存在
		b.Res.Code = ErrNotFound
		b.Res.Msg = "亲友圈不存在"
		b.Response()
		return
	}
	//根据union_id获取玩家信息
	pa, err := client.PassportInfoByUnionId(p.UnionId)
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}
	if pa == nil {
		b.Res.Code = ErrNotFound
		b.Res.Msg = "用户未注册,请下载游戏"
		b.Response()
		return
	}

	//查找是否已经是此亲友圈成员(正常或禁言)，如果是无需重复加入
	status, _, ok := client.IsClubMemberExist(p.ClubId, pa.Uid)
	if ok {
		if status == ClubMemberNormal || status == ClubMemberMute {
			b.Res.Msg = "您已是此亲友圈成员,无需重复加入"
			b.Res.Code = ErrAlreadyExist
			b.Response()
			return
		} else if status == ClubMemberAudit {
			b.Res.Msg = "您已申请加入,请耐心等待审核"
			b.Res.Code = ErrAlreadyExist
			b.Response()
			return
		}
	}
	//获取亲友圈人数限制
	rule, err := h5.RuleByType(RuleClubMemberNum)
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}
	if rule.Id != 0 {
		if rule.Amount <= club.Member {
			b.ResponseFail("加入失败,亲友圈成员已达上限")
			return
		}
	} else {
		LogClient.Error("亲友圈成员数限制未设置,请限制")
	}
	cm := map[string]interface{}{
		"uid":         pa.Uid,
		"cid":         p.ClubId,
		"role":        ClubRoleNormal,
		"status":      ClubMemberAudit,
		"create_time": time.Now().Unix(),
	}

	msg := GenBroadcastMsg(ModuleClub, ActionJoinClub, p.ClubId)
	if club.IsAudit == 0 { //不需要审核
		cm["status"] = ClubMemberNormal
		_, err = client.NewClubMember(cm)
		if err != nil {
			LogClient.Error(b.DatabaseError(err.Error()))
			return
		}

		//更新亲友圈成员总数
		client.UpdateClubMemberNum(p.ClubId)
		//添加亲友圈成员到redis里,
		Key := fmt.Sprintf("%v%v", KeyClub, p.ClubId)
		Redis.HSet(Key, pa.Uid, pa.Uid)

		//通知申请者
		msg = GenBroadcastMsg(ModuleClub, ActionJoinClubSuccess, p.ClubId)
		client.BroadCastMsgToLobby(0, msg, pa.Uid) //发送消息给申请者，提示它你已成功加入

		//实时通知创建人及管理员有新成员申请加入,好让他们及时审核,不用发邮件
		client.NotifyClubHostAndAdmin(p.ClubId, msg)
		b.ResponseSuccessTwo("加入成功,你已是亲友圈成员")
	} else { //需要审核
		//如果曾经加入过，再次加入时会直接把状态改为未审核,并且把之前的数据都归为默认的
		_, err = client.NewClubMember(cm)
		if err != nil {
			LogClient.Error(b.DatabaseError(err.Error()))
			return
		}
		//实时通知创建人及管理员有新成员申请加入,好让他们及时审核,不用发邮件
		client.NotifyClubHostAndAdmin(p.ClubId, msg)
		b.ResponseSuccess("加入成功,请等待审核")
	}
}

// @Title 根据code获取union_id
// @Description 根据code获取union_id
// @Param   code       body    string  true      "微信用户code"
// @Success 0 {string} token
// @Failure 400
// @Failure 404
// @router /user-info [post]
func (b *ClientController) UserInfo() {
	type Params struct {
		Code string `json:"code" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.VerifyParamsError() {
		return
	}

	t, err := login.GetWeChatOpenIdAccessToken(p.Code)
	if err != nil {
		LogClient.Error(b.SystemError(err.Error()))
		return
	}
	if t.AccessToken == "" || t.OpenId == "" {
		LogClient.Error(b.SystemError(fmt.Sprintf("无效的open_id:%v\naccess_token:%v\n", t.OpenId, t.AccessToken)))
		return
	}
	weChat, err := login.GetWeChatUserInfo(t.AccessToken, t.OpenId)
	if err != nil {
		LogClient.Error(b.SystemError(err.Error()))
		return
	}
	if weChat == nil {
		b.Res.Code = ErrNotFound
		b.Res.Msg = MsgErrUserNotFound
		b.Response()
		return
	}
	b.Res.Data = weChat.UnionID
	b.ResponseSuccess()
}
